package com.yxc.websocketclientdemo;

import android.annotation.TargetApi;
import android.app.AppOpsManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.ApplicationInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.yxc.websocketclientdemo.adapter.Adapter_ChatMessage;
import com.yxc.websocketclientdemo.adapter.EmotionGridViewAdapter;
import com.yxc.websocketclientdemo.adapter.EmotionPagerAdapter;
import com.yxc.websocketclientdemo.emotionkeyboardview.EmojiIndicatorView;
import com.yxc.websocketclientdemo.emotionkeyboardview.EmotionKeyboard;
import com.yxc.websocketclientdemo.fragment.EmotionMainFragment;
import com.yxc.websocketclientdemo.im.JWebSocketClient;
import com.yxc.websocketclientdemo.im.JWebSocketClientService;
import com.yxc.websocketclientdemo.modle.ChatMessage;
import com.yxc.websocketclientdemo.util.Util;
import com.yxc.websocketclientdemo.utils.DisplayUtils;
import com.yxc.websocketclientdemo.utils.EmotionUtils;
import com.yxc.websocketclientdemo.utils.GlobalOnItemClickManagerUtils;
import com.yxc.websocketclientdemo.utils.ScreenUtils;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;


public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Context mContext;
    private JWebSocketClient client;
    private JWebSocketClientService.JWebSocketClientBinder binder;
    private JWebSocketClientService jWebSClientService;
    private EditText et_content;
    private ListView listView;
    private Button btn_send;
    private FrameLayout frame;
    private List<ChatMessage> chatMessageList = new ArrayList<>();//消息列表
    private Adapter_ChatMessage adapter_chatMessage;
    private ChatMessageReceiver chatMessageReceiver;


    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            Log.e("MainActivity", "服务与活动成功绑定");
            binder = (JWebSocketClientService.JWebSocketClientBinder) iBinder;
            jWebSClientService = binder.getService();
            client = jWebSClientService.client;
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.e("MainActivity", "服务与活动成功断开");
        }
    };

    private class ChatMessageReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String message = intent.getStringExtra("message");
            ChatMessage chatMessage = new ChatMessage();
            chatMessage.setContent(message);
            chatMessage.setIsMeSend(0);
            chatMessage.setIsRead(1);
            chatMessage.setTime(System.currentTimeMillis() + "");
            chatMessageList.add(chatMessage);
            initChatMsgListView();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().hide();
        setContentView(R.layout.activity_main1);
        mContext = MainActivity.this;
        //启动服务
        startJWebSClientService();
        //绑定服务
        bindService();
        //注册广播
        doRegisterReceiver();
        //检测通知是否开启
        checkNotification(mContext);
        findViewById();
    }

    private EmotionMainFragment emotionMainFragment;

    /**
     * 绑定服务
     */
    private void bindService() {
        Intent bindIntent = new Intent(mContext, JWebSocketClientService.class);
        bindService(bindIntent, serviceConnection, BIND_AUTO_CREATE);
    }

    /**
     * 启动服务（websocket客户端服务）
     */
    private void startJWebSClientService() {
        Intent intent = new Intent(mContext, JWebSocketClientService.class);
        startService(intent);
    }

    /**
     * 动态注册广播
     */
    private void doRegisterReceiver() {
        chatMessageReceiver = new ChatMessageReceiver();
        IntentFilter filter = new IntentFilter("com.xch.servicecallback.content");
        registerReceiver(chatMessageReceiver, filter);
    }

    private ImageView btn_face;
    private ViewPager vp_complate_emotion_layout;
    private EmojiIndicatorView ll_point_group;//表情面板对应的点列表
    //需要绑定的内容view
    private View contentView;

    private void findViewById() {
        vp_complate_emotion_layout = (ViewPager) findViewById(R.id.vp_complate_emotion_layout);
        ll_point_group = (EmojiIndicatorView) findViewById(R.id.ll_point_group);
        frame = findViewById(R.id.frame);
        listView = findViewById(R.id.chatmsg_listView);
        btn_face = findViewById(R.id.btn_face);
        initViewList();
        btn_send = findViewById(R.id.btn_send);
        et_content = findViewById(R.id.et_content);
        btn_send.setOnClickListener(this);

        initAnimations();

        EmotionKeyboard mEmotionKeyboard = EmotionKeyboard.with(this)
                .setEmotionView(findViewById(R.id.ll_emotion_layout))//绑定表情面板
                .bindToContent(frame)//绑定内容view
                .bindToEditText(et_content)//判断绑定那种EditView
                .bindToEmotionButton(btn_face)//绑定表情按钮
                .build();

        //创建全局监听
        GlobalOnItemClickManagerUtils globalOnItemClickManager = GlobalOnItemClickManagerUtils.getInstance(this);
        globalOnItemClickManager.attachToEditText(et_content);
        initEmotion();
        initListener();
    }

    /**
     * 初始化监听器
     */
    protected void initListener() {

        vp_complate_emotion_layout.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            int oldPagerPos = 0;

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                ll_point_group.playByStartPointToNext(oldPagerPos, position);
                oldPagerPos = position;
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

    private EmotionPagerAdapter emotionPagerGvAdapter;

    /**
     * 初始化表情面板
     * 思路：获取表情的总数，按每行存放7个表情，动态计算出每个表情所占的宽度大小（包含间距），
     * 而每个表情的高与宽应该是相等的，这里我们约定只存放3行
     * 每个面板最多存放7*3=21个表情，再减去一个删除键，即每个面板包含20个表情
     * 根据表情总数，循环创建多个容量为20的List，存放表情，对于大小不满20进行特殊
     * 处理即可。
     */
    private void initEmotion() {
        // 获取屏幕宽度
        int screenWidth = DisplayUtils.getScreenWidthPixels(this);
        // item的间距
        int spacing = DisplayUtils.dp2px(this, 7);
        // 动态计算item的宽度和高度
        int itemWidth = (screenWidth - spacing * 8) / 7;
        //动态计算gridview的总高度
        int gvHeight = itemWidth * 4 + spacing * 7;

        List<GridView> emotionViews = new ArrayList<>();
        List<String> emotionNames = new ArrayList<>();
        // 遍历所有的表情的key
        for (String emojiName : EmotionUtils.EMOTION_CLASSIC_MAP.keySet()) {
            emotionNames.add(emojiName);
            // 每20个表情作为一组,同时添加到ViewPager对应的view集合中
            if (emotionNames.size() == 27) {
                GridView gv = createEmotionGridView(emotionNames, screenWidth, spacing, itemWidth, gvHeight);
                emotionViews.add(gv);
                // 添加完一组表情,重新创建一个表情名字集合
                emotionNames = new ArrayList<>();
            }
        }

        // 判断最后是否有不足20个表情的剩余情况
        if (emotionNames.size() > 0) {
            GridView gv = createEmotionGridView(emotionNames, screenWidth, spacing, itemWidth, gvHeight);
            emotionViews.add(gv);
        }

        //初始化指示器
        ll_point_group.initIndicator(emotionViews.size());
        // 将多个GridView添加显示到ViewPager中
        emotionPagerGvAdapter = new EmotionPagerAdapter(emotionViews);
        vp_complate_emotion_layout.setAdapter(emotionPagerGvAdapter);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(screenWidth, gvHeight);
        vp_complate_emotion_layout.setLayoutParams(params);
    }

    /**
     * 创建显示表情的GridView
     */
    private GridView createEmotionGridView(List<String> emotionNames, int gvWidth, int padding, int itemWidth, int gvHeight) {
        // 创建GridView
        GridView gv = new GridView(this);
        //设置点击背景透明
        gv.setSelector(android.R.color.transparent);
        //设置7列
        gv.setNumColumns(7);
        gv.setPadding(padding, padding, padding, padding);
        gv.setHorizontalSpacing(padding);
        gv.setVerticalSpacing(padding + 10);
        //设置GridView的宽高
        ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(gvWidth, gvHeight);
        gv.setLayoutParams(params);
        // 给GridView设置表情图片
        EmotionGridViewAdapter adapter = new EmotionGridViewAdapter(this, emotionNames, itemWidth, EmotionUtils.EMOTION_CLASSIC_TYPE);
        gv.setAdapter(adapter);
        //设置全局点击事件
        gv.setOnItemClickListener(GlobalOnItemClickManagerUtils.getInstance(this).getOnItemClickListener(EmotionUtils.EMOTION_CLASSIC_TYPE));
        return gv;
    }

    private List<View> viewList = new ArrayList<>();
    private List<ImageView> headPicList = new ArrayList<>();
    private List<TextView> ncNameList = new ArrayList<>();
    private List<TextView> textContentList = new ArrayList<>();

    private View child0, child1, child2, child3, child4, child5, child6, child7, child8, child9;
    private ImageView headPic0, headPic1, headPic2, headPic3, headPic4, headPic5, headPic6, headPic7, headPic8, headPic9;
    private TextView ncName0, ncName1, ncName2, ncName3, ncName4, ncName5, ncName6, ncName7, ncName8, ncName9;
    private TextView textContent0, textContent1, textContent2, textContent3, textContent4, textContent5, textContent6, textContent7, textContent8, textContent9;

    private void initViewList() {
        child0 = findViewById(R.id.child0);
        child1 = findViewById(R.id.child1);
        child2 = findViewById(R.id.child2);
        child3 = findViewById(R.id.child3);
        child4 = findViewById(R.id.child4);
        child5 = findViewById(R.id.child5);
        child6 = findViewById(R.id.child6);
        child7 = findViewById(R.id.child7);
        child8 = findViewById(R.id.child8);
        child9 = findViewById(R.id.child9);
        viewList.add(child0);
        viewList.add(child1);
        viewList.add(child2);
        viewList.add(child3);
        viewList.add(child4);
        viewList.add(child5);
        viewList.add(child6);
        viewList.add(child7);
        viewList.add(child8);
        viewList.add(child9);


        headPic0 = findViewById(R.id.headPic0);
        headPic1 = findViewById(R.id.headPic1);
        headPic2 = findViewById(R.id.headPic2);
        headPic3 = findViewById(R.id.headPic3);
        headPic4 = findViewById(R.id.headPic4);
        headPic5 = findViewById(R.id.headPic5);
        headPic6 = findViewById(R.id.headPic6);
        headPic7 = findViewById(R.id.headPic7);
        headPic8 = findViewById(R.id.headPic8);
        headPic9 = findViewById(R.id.headPic9);
        headPicList.add(headPic0);
        headPicList.add(headPic1);
        headPicList.add(headPic2);
        headPicList.add(headPic3);
        headPicList.add(headPic4);
        headPicList.add(headPic5);
        headPicList.add(headPic6);
        headPicList.add(headPic7);
        headPicList.add(headPic8);
        headPicList.add(headPic9);

        ncName0 = findViewById(R.id.ncName0);
        ncName1 = findViewById(R.id.ncName1);
        ncName2 = findViewById(R.id.ncName2);
        ncName3 = findViewById(R.id.ncName3);
        ncName4 = findViewById(R.id.ncName4);
        ncName5 = findViewById(R.id.ncName5);
        ncName6 = findViewById(R.id.ncName6);
        ncName7 = findViewById(R.id.ncName7);
        ncName8 = findViewById(R.id.ncName8);
        ncName9 = findViewById(R.id.ncName9);
        ncNameList.add(ncName0);
        ncNameList.add(ncName1);
        ncNameList.add(ncName2);
        ncNameList.add(ncName3);
        ncNameList.add(ncName4);
        ncNameList.add(ncName5);
        ncNameList.add(ncName6);
        ncNameList.add(ncName7);
        ncNameList.add(ncName8);
        ncNameList.add(ncName9);

        textContent0 = findViewById(R.id.textContent0);
        textContent1 = findViewById(R.id.textContent1);
        textContent2 = findViewById(R.id.textContent2);
        textContent3 = findViewById(R.id.textContent3);
        textContent4 = findViewById(R.id.textContent4);
        textContent5 = findViewById(R.id.textContent5);
        textContent6 = findViewById(R.id.textContent6);
        textContent7 = findViewById(R.id.textContent7);
        textContent8 = findViewById(R.id.textContent8);
        textContent9 = findViewById(R.id.textContent9);
        textContentList.add(textContent0);
        textContentList.add(textContent1);
        textContentList.add(textContent2);
        textContentList.add(textContent3);
        textContentList.add(textContent4);
        textContentList.add(textContent5);
        textContentList.add(textContent6);
        textContentList.add(textContent7);
        textContentList.add(textContent8);
        textContentList.add(textContent9);
    }

    private List<View> animingList = new ArrayList<>();
    /**
     * 初始化动画
     */
    private List<Animation> animList = new ArrayList<>();

    private void initAnimations() {
        for (int i = 0; i < 10; i++) {
            final int index = i;
            Animation animation = AnimationUtils.loadAnimation(this, R.anim.view_animation);
            animation.setAnimationListener(new Animation.AnimationListener() {

                @Override
                public void onAnimationStart(Animation animation) {//动画开始的时候的监听，
                    animingList.add(viewList.get(index));
                    viewList.get(index).setVisibility(View.VISIBLE);
                }

                @Override
                public void onAnimationRepeat(Animation animation) {//动画重复的时候监听
                }

                @Override
                public void onAnimationEnd(Animation animation) {//动画结束的时候监听
                    viewList.get(index).setVisibility(View.GONE);
                    animingList.remove(viewList.get(index));
                }
            });
            animList.add(animation);
        }
    }


    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_send:
                String ncName = new Random().nextInt(10000) + "";
                String contents = "xxxxxx";
                for (int i = 0; i < 10; i++) {
                    if (animingList.contains(viewList.get(i))) {
                        continue;
                    } else {
                        ncNameList.get(i).setText(ncName);
                        textContentList.get(i).setText(contents);
                        viewList.get(i).startAnimation(animList.get(i));
                        break;
                    }
                }

                String content = et_content.getText().toString();
                if (content.length() <= 0) {
                    Util.showToast(mContext, "消息不能为空哟");
                    return;
                }

                if (client != null && client.isOpen()) {
                    jWebSClientService.sendMsg(content);

                    //暂时将发送的消息加入消息列表，实际以发送成功为准（也就是服务器返回你发的消息时）
                    ChatMessage chatMessage = new ChatMessage();
                    chatMessage.setContent(content);
                    chatMessage.setIsMeSend(1);
                    chatMessage.setIsRead(1);
                    chatMessage.setTime(System.currentTimeMillis() + "");
                    chatMessageList.add(chatMessage);
                    initChatMsgListView();
                    et_content.setText("");
                } else {
                    Util.showToast(mContext, "连接已断开，请稍等或重启App哟");
                }
                break;
            default:
                break;
        }
    }

    private void initChatMsgListView() {
        adapter_chatMessage = new Adapter_ChatMessage(mContext, chatMessageList);
        listView.setAdapter(adapter_chatMessage);
        listView.setSelection(chatMessageList.size());
    }


    /**
     * 检测是否开启通知
     *
     * @param context
     */
    private void checkNotification(final Context context) {
        if (!isNotificationEnabled(context)) {
            new AlertDialog.Builder(context).setTitle("温馨提示")
                    .setMessage("你还未开启系统通知，将影响消息的接收，要去开启吗？")
                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            setNotification(context);
                        }
                    }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {

                }
            }).show();
        }
    }

    /**
     * 如果没有开启通知，跳转至设置界面
     *
     * @param context
     */
    private void setNotification(Context context) {
        Intent localIntent = new Intent();
        //直接跳转到应用通知设置的代码：
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            localIntent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
            localIntent.putExtra("app_package", context.getPackageName());
            localIntent.putExtra("app_uid", context.getApplicationInfo().uid);
        } else if (android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
            localIntent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            localIntent.addCategory(Intent.CATEGORY_DEFAULT);
            localIntent.setData(Uri.parse("package:" + context.getPackageName()));
        } else {
            //4.4以下没有从app跳转到应用通知设置页面的Action，可考虑跳转到应用详情页面,
            localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            if (Build.VERSION.SDK_INT >= 9) {
                localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
                localIntent.setData(Uri.fromParts("package", context.getPackageName(), null));
            } else if (Build.VERSION.SDK_INT <= 8) {
                localIntent.setAction(Intent.ACTION_VIEW);
                localIntent.setClassName("com.android.settings", "com.android.setting.InstalledAppDetails");
                localIntent.putExtra("com.android.settings.ApplicationPkgName", context.getPackageName());
            }
        }
        context.startActivity(localIntent);
    }

    /**
     * 获取通知权限,监测是否开启了系统通知
     *
     * @param context
     */
    @TargetApi(Build.VERSION_CODES.KITKAT)
    private boolean isNotificationEnabled(Context context) {

        String CHECK_OP_NO_THROW = "checkOpNoThrow";
        String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION";

        AppOpsManager mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        ApplicationInfo appInfo = context.getApplicationInfo();
        String pkg = context.getApplicationContext().getPackageName();
        int uid = appInfo.uid;

        Class appOpsClass = null;
        try {
            appOpsClass = Class.forName(AppOpsManager.class.getName());
            Method checkOpNoThrowMethod = appOpsClass.getMethod(CHECK_OP_NO_THROW, Integer.TYPE, Integer.TYPE,
                    String.class);
            Field opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION);

            int value = (Integer) opPostNotificationValue.get(Integer.class);
            return ((Integer) checkOpNoThrowMethod.invoke(mAppOps, value, uid, pkg) == AppOpsManager.MODE_ALLOWED);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

}
